package com.edge.pbx.view;

import android.content.Context;
import android.content.res.TypedArray;
import android.os.Trace;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.widget.FrameLayout;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.edge.pbxdsp.R;
import com.qztech.utils.YzDebug;

import static android.widget.FrameLayout.LayoutParams.UNSPECIFIED_GRAVITY;

/**
 * Copyright (C), 深圳市东乘电子科技有限公司
 * Carate By YangZhong
 */
public class YzPercentLayout extends FrameLayout {


    public YzPercentLayout(Context context, AttributeSet attrs) {
        super(context, attrs);

    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        final int width = MeasureSpec.getSize(widthMeasureSpec);
        final int height = MeasureSpec.getSize(heightMeasureSpec);
        YzDebug.d("Yang" ,"onMeasure :"+ width +"  " + height);
        View view = null;
        for (int i = 0, len = getChildCount(); i < len; i++) {
            view = getChildAt(i);
            LayoutParams lp = (LayoutParams) view.getLayoutParams();

            lp.setParentWH(width, height);
            if (isValid(lp.mLpWidth) && isValid(lp.mLpHeigh)) {
                view.measure(MeasureSpec.makeMeasureSpec(lp.mLpWidth.getValue(), MeasureSpec.EXACTLY),
                        MeasureSpec.makeMeasureSpec(lp.mLpHeigh.getValue(), MeasureSpec.EXACTLY));
                YzDebug.d("Yang","--onMeasure:"+i +"   w:"+ lp.mLpWidth.getValue()+
                        "  wp:"+lp.mLpWidth.percent+" h:"+ lp.mLpHeigh.getValue());
            } else {
                measureChild(view, MeasureSpec.makeMeasureSpec(width, MeasureSpec.AT_MOST),
                        MeasureSpec.makeMeasureSpec(height, MeasureSpec.AT_MOST));
            }

        }
        setMeasuredDimension(width, height);
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        final int width = r - l;
        final int height = b - t;
        View view = null;
        int cw = 0, ch = 0;
        for (int i = 0, len = getChildCount(); i < len; i++) {
            l = 0;
            t = 0;
            view = getChildAt(i);
            LayoutParams lp = (LayoutParams) view.getLayoutParams();

            cw = view.getMeasuredWidth();
            ch = view.getMeasuredHeight();
            //l t r b  g
            if (lp.gravity == UNSPECIFIED_GRAVITY) {
                lp.gravity = Gravity.NO_GRAVITY;
            }
            int gx = lp.gravity & 0xF;
            int gy = (lp.gravity >> Gravity.AXIS_Y_SHIFT) & 0xF;
            switch (gx) {
                case 0x01://center
                    l = (width - cw) >> 1;
                    break;
                case 0x05://
                    l = width - cw - lp.rightMargin - getLpValue(lp.mLpEnd);
                    break;
                case 0x03://left
                default:
                    l = lp.leftMargin + getLpValue(lp.mLpStart);
                    break;
            }
            switch (gy) {
                case 0x01:
                    t = (height - ch) >> 1;
                    break;
                case 0x05:
                    t = height - ch - lp.bottomMargin - getLpValue(lp.mLpBottom);
                    break;
                case 0x03://top
                default:
                    t = lp.topMargin + getLpValue(lp.mLpTop);
                    break;
            }
//            Log.d("Yang", ">>>>>>>>>>1i:" + i + " l:" + l + " t:" + t + " cw:" + cw + " ch:" + ch);

            view.layout(l, t, l + cw, t + ch);

        }
    }


    @Override
    public FrameLayout.LayoutParams generateLayoutParams(AttributeSet attrs) {

        return new LayoutParams(getContext(), attrs);
    }


    public static class LayoutParams extends FrameLayout.LayoutParams {
        private int mParentW, mParentH;
        LpItem mLpWidth;
        LpItem mLpHeigh;
        LpItem mLpStart, mLpEnd, mLpTop, mLpBottom;
        int mHCenterToId = View.NO_ID;
        int mVCenterToId = View.NO_ID;

        //w h l t r b
        public LayoutParams(@NonNull Context c, @Nullable AttributeSet attrs) {
            super(c, attrs);
            if (c == null || attrs == null) return;
            TypedArray array = c.obtainStyledAttributes(attrs, R.styleable.YzPercentLayout);
            int attr = 0;
            for (int i = 0, count = array.getIndexCount(); i < count; i++) {
                attr = array.getIndex(i);
                switch (attr) {
                    case R.styleable.YzPercentLayout_yzpercent_width:
                        mLpWidth = makeLpItem(array.getString(attr));
                        break;
                    case R.styleable.YzPercentLayout_yzpercent_height:
                        mLpHeigh = makeLpItem(array.getString(attr));
                        break;
                    case R.styleable.YzPercentLayout_yzpercent_margin_start:
                        mLpStart = makeLpItem(array.getString(attr));
                        break;
                    case R.styleable.YzPercentLayout_yzpercent_margin_end:
                        mLpEnd = makeLpItem(array.getString(attr));
                        break;
                    case R.styleable.YzPercentLayout_yzpercent_margin_top:
                        mLpTop = makeLpItem(array.getString(attr));
                        break;
                    case R.styleable.YzPercentLayout_yzpercent_margin_bottom:
                        mLpBottom = makeLpItem(array.getString(attr));
                        break;
                    case R.styleable.YzPercentLayout_yzpercent_hcenter_to:
                        mHCenterToId = array.getResourceId(attr, View.NO_ID);
                        break;
                    case R.styleable.YzPercentLayout_yzpercent_vcenter_to:
                        mVCenterToId = array.getResourceId(attr, View.NO_ID);
                        break;
                }
            }
            array.recycle();
        }

        public void setParentWH(int parentW, int parentH) {
            mParentW = parentW;
            mParentH = parentH;
        }

        private LpItem makeLpItem(String p) {
            YzDebug.d("Yang", "makeLpItem:" + p);
            if (p == null) return null;
            final int len = p.length();
            if (len < 3) return null;
            LpItem item = new LpItem();
            switch (p.substring(p.length() - 2)) {
                case "pw":
                    item.mReferType = ReferType.PARENT_WIDTH;
                    break;
                case "ph":
                    item.mReferType = ReferType.PARENT_HEIGHT;
                    break;
                case "sw":
                    item.mReferType = ReferType.SELF_WIDTH;
                    break;
                case "sh":
                    item.mReferType = ReferType.SELF_HEIGHT;
                    break;
                default:
                    YzDebug.d("makeLpItem error:" + p);
                    return null;
            }
            try {
                item.percent = Float.parseFloat(p.substring(0, len - 2));
                YzDebug.d("Yang", "makeLpItem:" + p + " " + item);
                return item;
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }

        public int getWidth() {
            if (isValid(mLpWidth)) {
                if (mLpWidth.mReferType == ReferType.SELF_WIDTH) {
                    return mParentW;
                }
                return mLpWidth.getValue();
            }
            return 0;
        }

        public int getHeight() {
            if (isValid(mLpHeigh)) {
                if (mLpHeigh.mReferType == ReferType.SELF_HEIGHT) {
                    return mParentH;
                }
                return mLpHeigh.getValue();
            }
            return 0;
        }

        private class LpItem {
            float percent = Float.NaN;
            ReferType mReferType;

            int getValue() {
                switch (mReferType) {
                    case PARENT_WIDTH:
                        return (int) (percent * mParentW);
                    case PARENT_HEIGHT:
                        return (int) (percent * mParentH);
                    case SELF_WIDTH:
                        return (int) (getWidth() * percent);
                    case SELF_HEIGHT:
                        return (int) (getHeight() * percent);
                }
                return (mParentW + mParentH) / 2;
            }


            @Override
            public String toString() {
                final StringBuffer sb = new StringBuffer("LpItem{");
                sb.append("percent=").append(percent);
                sb.append(", mReferType=").append(mReferType);
                sb.append('}');
                return sb.toString();
            }
        }
    }

    private enum ReferType {
        PARENT_WIDTH, PARENT_HEIGHT, SELF_WIDTH, SELF_HEIGHT
    }

    private static int getLpValue(LayoutParams.LpItem item) {
        if (item == null || item.percent == Float.NaN)
            return 0;
        return item.getValue();
    }

    private static boolean isValid(LayoutParams.LpItem... items) {
        if (items == null || items.length == 0) return false;
        for (LayoutParams.LpItem item : items) {
            if (item == null || item.percent == Float.NaN)
                return false;
        }
        return true;
        //   if (item != null){
        //       return item.percent != Float.NaN;
        //   }
        //   return false;
    }
}
